package site.wlwsjsx.iot_backend.utils;

import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;

/**
 * 盐值加密工具类
 * 使用PBKDF2WithHmacSHA256算法进行密码加密
 */
public class SaltEncryptionUtil {
    // 加密算法参数
    private static final int ITERATIONS = 65536;
    private static final int KEY_LENGTH = 256;
    private static final String ALGORITHM = "PBKDF2WithHmacSHA256";

    /**
     * 生成一个随机的盐值(Salt)
     *
     * @return 返回一个Base64编码的随机盐值字符串
     */
    public static String generateSalt() {
        // 创建一个安全的随机数生成器
        SecureRandom random = new SecureRandom();
        // 创建一个长度为16的字节数组用于存储盐值
        byte[] salt = new byte[16];
        // 生成随机字节并填充到盐值数组中
        random.nextBytes(salt);
        // 将字节数组转换为Base64编码的字符串并返回
        return Base64.getEncoder().encodeToString(salt);
    }

    /**
     * 加密密码
     *
     * @param password 原始密码
     * @param salt     盐值
     * @return 加密后的密码
     */
    public static String encryptPassword(String password, String salt) {
        try {
            byte[] saltBytes = Base64.getDecoder().decode(salt);
            PBEKeySpec spec = new PBEKeySpec(
                    password.toCharArray(),
                    saltBytes,
                    ITERATIONS,
                    KEY_LENGTH
            );
            SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
            byte[] hash = factory.generateSecret(spec).getEncoded();
            return Base64.getEncoder().encodeToString(hash);
        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            throw new RuntimeException("密码加密失败", e);
        }
    }

    /**
     * 验证密码
     *
     * @param rawPassword       原始密码
     * @param encryptedPassword 加密后的密码
     * @param salt              盐值
     * @return 验证结果
     */
    public static boolean verifyPassword(String rawPassword, String encryptedPassword, String salt) {
        String hashedPassword = encryptPassword(rawPassword, salt);
        return hashedPassword.equals(encryptedPassword);
    }
}
